package win.devhu.testing.SpringBoot2Kotlin.jpaDemo

import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*
import win.devhu.testing.SpringBoot2Kotlin.jpaDemo.entity.Address
import win.devhu.testing.SpringBoot2Kotlin.jpaDemo.entity.User
import win.devhu.testing.SpringBoot2Kotlin.jpaDemo.repositories.AddressRepository
import win.devhu.testing.SpringBoot2Kotlin.jpaDemo.repositories.UserRepository

@RestController
@RequestMapping("/api")
class RestWebController (){

    @Autowired //通过@Autowired自动装配方式,对类成员变量、方法及构造函数进行标注消除 set ，get方法
    lateinit var userRepository :UserRepository     //使用lateinit修饰，不用在定义的时候赋值
    @Autowired
    lateinit var addressRepository: AddressRepository

    private val logger: Logger = LoggerFactory.getLogger(RestWebController::class.java)

    @PostMapping("/save/user")
    fun saveUser(@RequestBody user: User): User
    {
        user.address.forEach{it.user = user}    //踩坑记录：此处一定要对象赋值，否则联级保存时外键（user_id）一直为空
        return userRepository.save(user)
    }

    @GetMapping("/users")
    fun getUsers() : Response{
        val users:MutableIterable<User> = userRepository.findAll()
        return Response(true, "",users)
    }

    @GetMapping("/user/{id}")
    fun getUser(@PathVariable id: Long) : Response{
        val user = userRepository.findById(id)
        if(user.isPresent){
            return Response(true, "",user)
        }else{
            return Response(false,msg = "未找到相关用户")
        }
    }

    @PutMapping("/user/{id}")
    fun updateUser(@PathVariable id: Long,@RequestBody user: User): User {
        user.id = id
        if (user.address != null){      //user.address = null 时只更新用户信息不更新地址信息，更新地址时需要传地址ID否则默认新增了
            user.address.forEach{it.user = user}
        }
        return userRepository.save(user)
    }

    @DeleteMapping("/user/{id}")
    fun deleteUser(@PathVariable id: Long) : Response{  //由于user 跟 address 是一对多关系此处删除user亦会删除对应用户所有的地址
        val user = userRepository.findById(id)
        if(user.isPresent){             //判断存在才删除；isPresent()：如果Optional包含的T实例不为null，则返回true；若T实例为null，返回false
            userRepository.deleteById(id)
            return Response(true,msg = "删除成功")
        }else{
            return Response(false,msg = "用户不存在")
        }
    }

    @GetMapping("/address")
    fun getAllAddress() : Response{
        val address = addressRepository.findAll()
        return Response(true, "",address)
    }

    /**
     * 此处更新保存时，不传user_id 获取不到user 对象，保存时外键为空，原因是@JsonIgnore 导致user不序列化默认是null
     * 不知道有什么办法可以解不
     * */
    @PostMapping("/save/{user_id}/address")  //某user添加地址
    fun saveAddress(@PathVariable userId: Long,@RequestBody address: Address): Address {
        logger.info(address.toString())
        val user = userRepository.findById(userId)
        address.user = user.get()
        return addressRepository.save(address)
    }

    @PutMapping("/address/{user_id}/{id}")  //修改地址
    fun updateAddress(@PathVariable user_id: Long,@PathVariable id: Long,@RequestBody address: Address): Address {
        address.id = id
        val user = userRepository.findById(user_id)
        address.user = user.get()
        return addressRepository.save(address)
    }

    @GetMapping("/address/{id}")
    fun getAddress(@PathVariable id: Long) : Response{
        val address = addressRepository.findById(id)
        if(address.isPresent){
            return Response(true, "",address)
        }else{
            return Response(false,msg = "未找到相关地址")
        }
    }

    @DeleteMapping("/address/{id}")
    fun deleteaddress(@PathVariable id: Long) : Response{  //此处删除地址并不会删除USER
        val address = addressRepository.findById(id)
        if(address.isPresent){             //判断存在才删除；isPresent()：如果Optional包含的T实例不为null，则返回true；若T实例为null，返回false
            addressRepository.deleteById(id)
            return Response(true,msg = "删除成功")
        }else{
            return Response(false,msg = "地址不存在")
        }
    }
}

/**
 * @RequestMapping   和  @GetMapping @PostMapping 区别
 * @GetMapping是一个组合注解，是@RequestMapping(method = RequestMethod.GET)的缩写。
 * @PostMapping是一个组合注解，是@RequestMapping(method = RequestMethod.POST)的缩写。
 * */